package com.ygqh.baby.controller.admin;

import com.ygqh.baby.annotation.ProductLog;
import com.ygqh.baby.ao.*;
import com.ygqh.baby.controller.utils.DocumentHandler;
import com.ygqh.baby.model.YgProduct4ListModel;
import com.ygqh.baby.model.YgSkuInfo;
import com.ygqh.baby.po.*;
import com.ygqh.baby.service.*;
import com.ygqh.baby.utils.HttpUtil;
import com.ygqh.baby.utils.InternetWormUtils;
import com.ygqh.baby.utils.JsonUtils;
import org.apache.shiro.util.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

@Controller
@RequestMapping("/admin/product")
public class ProductController extends BaseController<Object, java.lang.Long> {

    @Autowired
    private YgProductService ygProductService;
    @Autowired
    private YgCategoryService ygCategoryService;
    @Autowired
    private YgSkuService ygSkuService;
    @Autowired
    private FileService fileService;
    @Autowired
    private AdminSkuService adminSkuService;

    @RequestMapping("searchProduct")
    @ResponseBody
    public Map<String, Object> searchProduct(String q, QueryInfo queryInfo, String productStatus, Long groupId, String groupName, Boolean isSpecial, String productCode,
                                             Boolean isGroup, BigDecimal vipPrice, Long supplierId, String supplierName, Boolean preSaleDate, SalesPlatform salesPlatform) {

        if (isSpecial == false) {
            isSpecial = null;
        }
        supplierId = getSupplier().getId();

        ResultSet<Map<String, Object>> resultSet = ygProductService.search(queryInfo, q, groupName, productStatus, supplierName, isSpecial, productCode, isGroup, preSaleDate, salesPlatform);

        return resultSet.toDatatables(null);
    }

    @ProductLog(description = "新增/更新商品", params = {"product", "productCode"})
    @RequestMapping("saveProduct")
    @ResponseBody
    public Message saveProduct(String product, String productCode) throws Exception {
        YgProduct p = JsonUtils.toObject(product, YgProduct.class);
        Message validateCodeMsg = validateCode(p);
        if (!validateCodeMsg.getType().equals(Message.Type.success)) {
            return validateCodeMsg;
        }

        if (p.getId() != null) {
            p.setUpdateBy(getSession().getUserName());
            p.setUpdateTime(new Date());
            // 判断有新客价时 是否存在自选礼包活动
            if (!p.getNewCustomPrice().equals(BigDecimal.ZERO))
                if (ygProductService.IsExistPackByProductId(p.getId()))
                    return Message.error("商品已参与N元任选活动,不能设置新客价");
        } else {
            p.setCreateTime(new Date());
            p.setCreateBy(getSession().getUserName());
            p.setUpdateTime(p.getCreateTime());
            p.setUpdateBy(p.getCreateBy());
        }
        YgSupplier supplier = getSupplier();
        p.setForeverRate(new BigDecimal("0.05"));
        p.setShareRate(supplier.getShareRate());
        p.setSupplierId(supplier.getId());

        saveAdminSku(p);
        // 如果原产品编码与现在的产品编码不一致，则删除产品的sku
        if (!productCode.equals(p.getProductCode())) {
            YgSku ygSku = new YgSku();
            ygSku.setProductId(p.getId());
            ygSku.setStatus(DataStatus.Delete);
            ygSku.setUpdateBy(getSession().getUserName());
            ygSku.setUpdateTime(new Date());
            ygSkuService.updateByProductId(ygSku);
            adminSkuService.updateProduct(productCode, DataStatus.Delete.name());
        }

        if (ygProductService.saveOrUpdate(p) == 1) {
            return Message.success(p.getId());
        }
        return ERROR_MESSAGE;
    }

    /**
     * 验证商品编码和SKU编码
     *
     * @param product
     * @return
     */
    private Message validateCode(YgProduct product) {
        if (checkProductCode(product.getProductCode(), product.getId(), product.getPromotionType())) {
            return Message.error("商品编码已存在", product.getProductCode());
        }
        for (YgSku sku : product.getYgSkus()) {
            if (checkSkuCode(sku.getSkuCode(), sku.getId(), product.getPromotionType())) {
                return Message.error("SKU编码已存在", sku.getSkuCode());
            }
        }
        return Message.success(null);
    }

    private void saveAdminSku(YgProduct p) {
        List<AdminSku> adminSkuList = new ArrayList<>();
        Date createTime = new Date();
        String createBy = getSession().getUserName();
        for (YgSku sku : p.getYgSkus()) {
            if (sku.getId() == null) {
                AdminSku adminSku = new AdminSku();
                adminSku.setGroupId(p.getGroupId());
                adminSku.setSkuCode(sku.getSkuCode());
                adminSku.setProductCode(p.getProductCode());
                adminSku.setProductName(p.getProductName());
                adminSku.setColor(p.getShortName());
                adminSku.setSizeName(sku.getSizeName());
                adminSku.setCreateBy(createBy);
                adminSku.setCreateTime(createTime);
                adminSku.setStatus(DataStatus.Valid);
                adminSku.setIsCoats(false);
                adminSkuList.add(adminSku);
            } else if (sku.getStatus().equals(DataStatus.Delete)) {
                adminSkuService.updateSku(sku.getSkuCode(), DataStatus.Delete);
            } else {
                adminSkuService.updateSku(sku.getSkuCode(), DataStatus.Valid);
            }
        }
        adminSkuService.saveSkuBatch(adminSkuList, p.getUpdateBy());
    }

    @ProductLog(description = "删除商品", params = {"id"})
    @RequestMapping("updateProductStatus")
    @ResponseBody
    public Message updateProductStatus(Long id) {
        YgProduct ygProduct = new YgProduct();
        ygProduct.setId(id);
        ygProduct.setUpdateBy(getSession().getUserName());
        ygProduct.setUpdateTime(new Date());
        ygProduct.setStatus(DataStatus.Delete);

        YgSku ygSku = new YgSku();
        ygSku.setProductId(id);
        ygSku.setUpdateBy(getSession().getUserName());
        ygSku.setUpdateTime(new Date());
        ygSkuService.update(ygSku);

        return ygProductService.updateProductStatus(ygProduct) == 1 ? SUCCESS_MESSAGE : ERROR_MESSAGE;
    }

    @ProductLog(description = "上/下架商品", params = {"id", "saleStatus", "saleTime"})
    @RequestMapping("updateSalesStatus")
    @ResponseBody
    public Message updateSalesStatus(Long id, ProductStatus saleStatus, Date saleTime) {
        YgProduct ygProduct = new YgProduct();
        ygProduct.setId(id);
        ygProduct.setUpdateBy(getSession().getUserName());
        ygProduct.setUpdateTime(new Date());
        ygProduct.setSaleStatus(saleStatus);
        if (saleStatus.equals(ProductStatus.OnSale) && saleTime != null)
            ygProduct.setSaleTime(saleTime);
        if (saleStatus.equals(ProductStatus.OnSale) && saleTime == null)
            ygProduct.setSaleTime(new Date());
        Message msg = ygProductService.updateSaleStatus(ygProduct) == 1 ? SUCCESS_MESSAGE : ERROR_MESSAGE;
        if (msg.getType().equals(Message.Type.success)) {
            ygProductService.pushToWDT(id);
        }
        return msg;
    }

    @ProductLog(description = "设置商品预售", params = {"id", "preSaleDate"})
    @RequestMapping("updatePreSaleDate")
    @ResponseBody
    public Message updatePreSaleDate(Long id, Date preSaleDate) {
        return ygProductService.updatePreSaleDate(id, preSaleDate, getSession().getUserName()) == 1 ? SUCCESS_MESSAGE : ERROR_MESSAGE;
    }

    @RequestMapping("getProductById")
    @ResponseBody
    public YgProduct getProductById(Long id) {
        return ygProductService.findDetailById(id);
    }

    @RequestMapping("findProductByIds")
    @ResponseBody
    public List<YgProduct> findProductByIds(Long[] ids) {
        return ygProductService.findByIds(ids);
    }

    @RequestMapping("getProductByGroupId")
    @ResponseBody
    public YgProduct getProductByGroupId(Long groupId) {

        return ygProductService.findDetailByGroupId(groupId).get(0);

    }

    @RequestMapping("getParentCategory")
    @ResponseBody
    public List<YgCategory> getParentCategory() {
        return ygCategoryService.findTopLevel();
    }

    @RequestMapping("getCategoryByParentId")
    @ResponseBody
    public List<YgCategory> getCategoryByParentId(Long parentId) {
        return ygCategoryService.findByParentId(parentId);
    }

    @RequestMapping("searchProductList")
    @ResponseBody
    public Map<String, Object> searchProductList(String q, QueryInfo queryInfo, Long packId) {

        ResultSet<YgProduct4ListModel> result = ygProductService.findOrdinaryProductNotPack(q, queryInfo, packId);
        return result.toDatatables(null);
    }

    @RequestMapping("searchProductListForPromotion")
    @ResponseBody
    public Map<String, Object> searchProductListForPromotion(String q, Long groupId) {

        List<YgProduct> list = ygProductService.findProductForPromotion(null, q, groupId, null, 1L, null, null);
        ResultSet<YgProduct> result = new ResultSet<YgProduct>(1, list);

        return result.toDatatables(null);
    }

    @RequestMapping("searchOrdinaryProductList")
    @ResponseBody
    public Map<String, Object> searchOrdinaryProductList(String q, Long groupId) {

        List<YgProduct> list = ygProductService.findOrdinaryOnSaleProducts(q, groupId, null);
        ResultSet<YgProduct> result = new ResultSet<YgProduct>(1, list);
        return result.toDatatables(null);
    }

    @RequestMapping("getProductListToPromotion")
    @ResponseBody
    public Map<String, Object> getPromotion(Long promotionId, String productName, Long groupId) {
        QueryInfo queryInfo = new QueryInfo();
        queryInfo.setEnd(200);
        List<YgProduct> list = ygProductService.findProductForPromotion(queryInfo, productName, groupId, ProductStatus.OnSale.name(), 1L, promotionId, null);
        ResultSet<YgProduct> result = new ResultSet<YgProduct>(1, list);
        return result.toDatatables(null);
    }

    /**
     * 验证商品编码是否存在
     * true--已存在，false--不存在
     *
     * @param productCode
     * @param id
     * @return
     */
    @RequestMapping("checkProductCode")
    @ResponseBody
    public Boolean checkProductCode(String productCode, Long id, PromotionType promotionType) {
        List<YgProduct> productList = ygProductService.findByProductCodes(new String[]{productCode}, promotionType == null ? PromotionType.Ordinary : promotionType);
        if (CollectionUtils.isEmpty(productList)) {
            List<AdminSku> adminSkuList = adminSkuService.find(productCode);
            if (!CollectionUtils.isEmpty(adminSkuList)) {
                return true;
            }
        } else {
            List<Long> list = productList.stream().map(o -> o.getId()).collect(Collectors.toList());
            if (id == null || !list.contains(id)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 验证SKU编码是否存在
     * true--已存在，false--不存在
     *
     * @param skuCode
     * @param id
     * @return
     */
    @RequestMapping("checkSkuCode")
    @ResponseBody
    public Boolean checkSkuCode(String skuCode, Long id, PromotionType promotionType) {
        YgSku ygSku = ygSkuService.findBySkuCode(skuCode, promotionType == null ? PromotionType.Ordinary : promotionType);
        if (ygSku == null) {
            AdminSku adminSku = adminSkuService.findBySkuCode(skuCode);
            if (adminSku != null) {
                return true;
            }
        } else if (id == null || ygSku.getId().compareTo(id) != 0) {
            return true;
        }
        return false;
    }

    @RequestMapping("getParentsByCategoryId")
    @ResponseBody
    public List<YgCategory> getParentsByCategoryId(Long categoryId) {
        return ygCategoryService.findParentsByCategoryId(categoryId);
    }

    @RequestMapping("getSkuByProductId")
    @ResponseBody
    public List<YgSku> getSkuByProductId(Long productId) {
        return ygSkuService.find(productId);
    }

    @RequestMapping("updateWholesalePrice")
    @ResponseBody
    public Message updateWholesalePrice(String product) {
        YgProduct p = JsonUtils.toObject(product, YgProduct.class);
        ygProductService.updateWholesalePrice(p);
        return SUCCESS_MESSAGE;

    }

    @RequestMapping("updateCostPrice")
    @ResponseBody
    public Message updateCostPrice(String product) {
        YgProduct p = JsonUtils.toObject(product, YgProduct.class);
        ygProductService.updateCostPrice(p);
        return SUCCESS_MESSAGE;

    }

    @ProductLog(description = "商品一键改价", params = {"product"})
    @RequestMapping("updateSalesPrice")
    @ResponseBody
    public Message updateSalesPrice(String product) {
        YgProduct p = JsonUtils.toObject(product, YgProduct.class);
        ygProductService.updateSalesPrice(p);
        return Message.success(p.getId());

    }

    @ProductLog(description = "设置特例品", params = {"id", "isSpecial"})
    @RequestMapping("siteSpecial")
    @ResponseBody
    public Message siteSpecial(Long id, Boolean isSpecial) {
        return ygProductService.siteSpecial(id, isSpecial);
    }

    @RequestMapping("exportSkuCost")
    public void exportSkuCost(String productName, String productCode, String skuCode, Long groupId, HttpServletRequest request, HttpServletResponse response)
            throws IOException {
        if (groupId == -1)
            groupId = null;
        QueryInfo queryInfo = new QueryInfo();
        queryInfo.setEnd(2000);
        List<AdminSku> list = adminSkuService.selectSuperByProduct(queryInfo, productName, productCode, skuCode, groupId);

        // InputStream
        // inputStream=OrderController.class.getClassLoader().getResourceAsStream("/template/orderlist.xls");//"template/orderlist.xls";
        byte[] bytes = fileService.downloadFromOss("template/skuCost.xls"); // ByteToInputStream.input2byte(inputStream);
        List<Map<String, Object>> dataMaps = new ArrayList<Map<String, Object>>();
        Map<String, Object> dataMap = new HashMap<String, Object>();

        dataMap.put("resultSet", list);
        dataMaps.add(dataMap);
        DocumentHandler.DownloadExcel(bytes, "商品成本.xls", dataMap, request, response);
    }

    @RequestMapping("exportProduct")
    public void exportProduct(String productName, String productStatus, Long groupId, Boolean special, String productCode, Boolean isGroup, Long supplierId,
                              Boolean preDate, HttpServletRequest request, HttpServletResponse response) throws IOException {
        QueryInfo queryInfo = new QueryInfo();
        queryInfo.setEnd(2000000);
        List<YgProduct> list = ygProductService.selectProductList(queryInfo, productName, groupId, productStatus, supplierId, special, productCode, isGroup,
                PromotionType.Ordinary, null, preDate);

        byte[] bytes = fileService.downloadFromOss("template/productlist.xls");
        List<Map<String, Object>> dataMaps = new ArrayList<Map<String, Object>>();
        Map<String, Object> dataMap = new HashMap<String, Object>();

        dataMap.put("resultSet", list);
        dataMaps.add(dataMap);
        DocumentHandler.DownloadExcel(bytes, "产品信息.xls", dataMap, request, response);
    }

    @SuppressWarnings("deprecation")
    @RequestMapping("getProductImagesByTmall")
    @ResponseBody
    public YgProduct getProductImagesByTmall(String tid, HttpServletRequest request) throws Exception {
        String path = "https://detail.m.tmall.com/item.htm?id=" + tid;
        YgProduct p = InternetWormUtils.getTmallImgPath(path);
        String localpath = request.getRealPath("/");
        String targetPath = localpath + "/ShareProductImage/second_" + tid + ".jpg";
        String temptPath = HttpUtil.saveImageToDisk("http:" + p.getProductImages().get(0).getImagePath(), targetPath);
        File file = new File(temptPath);
        FileType[] fileType = new FileType[]{FileType.ProductListImage, FileType.ProductDetailImage, FileType.ProductShoppingCartImage};

        String iamgepath = fileService.uploadImage(file, fileType, ".jpg", false, request);

        p.getProductImages().get(0).setImagePath(iamgepath);

        return p;
    }

    @RequestMapping("getSkuInfo")
    @ResponseBody
    public YgSkuInfo getSkuInfo(String skuCode, PromotionType pType, HttpServletRequest request) throws Exception {
        YgSkuInfo skuInfo = ygSkuService.getSkuInfo(skuCode, pType);
        return skuInfo;
    }

}
